package com.margo.project.nio;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;



public class NioSocketServer {
	
	public static void main(String[] args) throws IOException {
		ServerSocketChannel serverSocketChannel=ServerSocketChannel.open();
		serverSocketChannel.configureBlocking(true);
		serverSocketChannel.bind(new InetSocketAddress(8806)) ;
		Selector selector=Selector.open();		
		//接收线程
		Thread accept=new Thread(()-> {
				while(true) {
					System.out.println("threadName:"+Thread.currentThread().getName());
					try {
						SocketChannel socketChannel = serverSocketChannel.accept();
						socketChannel.configureBlocking(false);
						socketChannel.register(selector, SelectionKey.OP_READ);
					} catch (IOException e) {
						e.printStackTrace();
					}
					
				}
		});
		accept.start();
		//转发线程
		Thread poller=new Thread(()-> {
			while(true) {
				int keyCount=0;
				try {
					//轮询 selector.select()会阻塞
					keyCount = selector.select(1000);
					//System.out.println("keyCount:"+keyCount);
				} catch (IOException e) {
					e.printStackTrace();
				}
				Iterator<SelectionKey> iterator =
		                    keyCount > 0 ? selector.selectedKeys().iterator() : null;
				while (iterator != null && iterator.hasNext()) {
		        	SelectionKey sk = iterator.next();
		        	if(sk.isReadable()) {
		        		SocketChannel channel = (SocketChannel) sk.channel();
		        		niohttp(channel); 
		        	}
				}//while
			}
		});
		poller.start();
	}
	
	public static void niohttp(SocketChannel channel)  {
		// 创建读取的缓冲区
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		try {
			int i=channel.read(buffer);
			System.out.println("channel.read:"+i);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		byte[] data = buffer.array();
		String msg = new String(data).trim();
		System.out.println(msg);
		
		//模拟http请求response报文
		StringBuilder sb=new StringBuilder();
		sb.append("HTTP/1.1 200\r\n");
		sb.append("Content-Type: application/json;charset=UTF-8\r\n");
		sb.append("Content-Length: 2\r\n");
		sb.append("Date: Wed, 07 Nov 2018 01:15:42 GMT\r\n");
		sb.append("\r\n");
		sb.append("ok\r\n");
		sb.append("\r\n");
		//将消息编码为字节数组
		byte[] bytes;
		try {
			bytes = sb.toString().getBytes("utf-8");
			//根据数组容量创建ByteBuffer  
			ByteBuffer writeBuffer=ByteBuffer.allocate(bytes.length);
			//将字节数组复制到缓冲区  
			writeBuffer.put(bytes);
			//flip操作  
			writeBuffer.flip();
			//发送缓冲区的字节数组  
			channel.write(writeBuffer);// 将消息回送给客户端
			//关闭，客户端才会收到消息
			channel.close();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}
